<?php

/**
 * @version     1.1
 * @author      Jose Luis Quintana <joseluismegateam@gmail.com>
 */
// Acceso restringido
defined('JL') or die('Acceso denegado');
define('JLIMAGE_LOCAL_URL', 1);
define('JLIMAGE_EXTERNAL_URL', 2);

/**
 * JLImage
 * Handler for images types: jpg, png and gif
 * @package     EP EasyPanel
 * @author      Jose Luis Quintana
 * @version     1.2
 * @copyright	Copyright (C) 2010 LBN Studio. All rights reserved
 * @access      public
 */
class JLImage {

    var $_image;
    var $_image_type;
    var $_mime_type;
    var $_original_filename;
    var $_original_image;
    var $_is_preserver = FALSE;
    var $_load_from = JLIMAGE_LOCAL_URL;
    var $_extension = NULL;
    var $_mime_types = array(
        IMAGETYPE_GIF => 'image/gif',
        IMAGETYPE_PNG => 'image/png',
        IMAGETYPE_JPEG => 'image/jpeg');
    var $_types_images = array(
        'gif' => IMAGETYPE_GIF,
        'png' => IMAGETYPE_PNG,
        'jpg' => IMAGETYPE_JPEG,
        'jpeg' => IMAGETYPE_JPEG);

    /**
     * JLImage::JLImage()
     * contructor from class JLImage.
     * @param string $file_path_image
     * @return void
     */
    function JLImage($file_path_image = NULL) {
        if (!is_null($file_path_image)) {
            $this->load($file_path_image);
        }
    }

    function isPreserver($value = TRUE) {
        $this->_is_preserver = $value;
    }

    /**
     * JLImage::load()
     * Load an image jpg, png or gif to manipulate.
     * @param string $file_path_image
     * @return void
     */
    function load($file_path_image) {
        $image = NULL;
        $load_from = JLIMAGE_LOCAL_URL;
        $image_info = array();
        $ext = NULL;

        if (filter_var($file_path_image, FILTER_VALIDATE_URL)) {
            $image = imagecreatefromstring(file_get_contents($file_path_image));
            $ext = $this->getExtensionFile($file_path_image);
            $image_type = $this->_types_images[$ext];
            $image_info = array(
                2 => $image_type,
                'mime' => $this->_mime_types[$image_type]
            );

            $load_from = JLIMAGE_EXTERNAL_URL;

            if (!$image) {
                return FALSE;
//                    throw new Exception('The URL "' . $file_path_image . '" does not exist or simply is not an image file type supported!');
            }
        } else {
            if (is_file($file_path_image)) {
                $image_info = getimagesize($file_path_image);
                $ext = $this->getExtensionFile($file_path_image);

                switch ($image_info[2]) {
                    case IMAGETYPE_GIF:
                        $image = imagecreatefromgif($file_path_image);
                        break;
                    case IMAGETYPE_PNG:
                        $image = imagecreatefrompng($file_path_image);
                        break;
                    case IMAGETYPE_JPEG:
                        $image = imagecreatefromjpeg($file_path_image);
                        break;
                    default:
                        return FALSE;
//                            throw new Exception("The file type '$image_info[2]' is not supported!");
                        break;
                }
            } else {
                return FALSE;
//                    throw new Exception('The file path image "' . $file_path_image . '" does not exist!');
            }
        }

        $this->_extension = $ext;
        $this->_load_from = $load_from;
        $this->_mime_type = $image_info['mime'];
        $this->_original_filename = $file_path_image;
        $this->_image_type = $image_info[2];
        $this->_image = $image;
        $this->_original_image = $image;

        return TRUE;
    }

    /**
     * JLImage::save()
     * Save image to filepath.
     * @param string $file_path_image
     * @param int $quality
     * @param bool $destroyResource
     * @return bool
     */
    function save($file_path_image = NULL, $quality = 100, $destroy_resource = TRUE) {
        if (!$this->_image)
            return;

        if ($this->_load_from == JLIMAGE_EXTERNAL_URL) {
            if (is_null($file_path_image)) {
                $file_path_image = basename($this->_original_filename);
            }
        } else {
            if (is_null($file_path_image)) {
                $file_path_image = $this->_original_filename;
            }
        }

        $ok = FALSE;
        $image_type = $this->_image_type;

        switch ($image_type) {
            case IMAGETYPE_GIF:
                $ok = imagegif($this->_image, $file_path_image);
                break;
            case IMAGETYPE_PNG:
                if ($quality > 10) {
                    $quality = 0;
                }

                $ok = imagepng($this->_image, $file_path_image, $quality);
                break;
            case IMAGETYPE_JPEG:
                $ok = imagejpeg($this->_image, $file_path_image, $quality);
                break;
        }

        if ($destroy_resource) {
            $this->imageDestroy();
        }

        return $ok;
    }

    private function getExtensionFile($filename) {
        $matches = array();
        preg_match('/\.([^\.]+)$/', $filename, $matches);
        return strtolower($matches[1]);
    }

    /**
     * JLImage::getName()
     * Returns original name from image file.
     * @return string
     */
    function getName() {
        return basename($this->_original_filename);
    }

    /**
     * JLImage::getPath()
     * Returns path from image file.
     * @return string
     */
    function getPath() {
        return $this->_original_filename;
    }

    /**
     * JLImage::getExtension()
     * Returns extension for image file.
     * @return string
     */
    function getExtension() {
        return $this->_extension;
    }

    /**
     * JLImage::getType()
     * Get type of image.
     * @return int
     */
    function getType() {
        return $this->_image_type;
    }

    /**
     * JLImage::display()
     * Display a image in browser.
     * @param int $image_type
     * @param int $quality
     * @param bool $destroy_resource
     * @return bool
     */
    function display($image_type = NULL, $quality = 100, $destroy_resource = TRUE) {
        $image = $this->_image;

        if (!$image)
            return;

        $mime_types = $this->_mime_types;
        $image_type = is_null($image_type) ? $this->_image_type : $image_type;

        ob_start();
        header('Content-type: ' . $mime_types[$image_type]);

        switch ($image_type) {
            case IMAGETYPE_GIF:
                $ok = imagegif($image, NULL);
                break;
            case IMAGETYPE_JPEG:
                $ok = imagejpeg($image, NULL, $quality);
                break;
            case IMAGETYPE_PNG:
                if ($quality > 10) {
                    $quality = 0;
                }

                $ok = imagepng($image, NULL, $quality);
                break;
        }

        if ($destroy_resource) {
            $this->imageDestroy();
        }

        ob_end_flush();
    }

    /**
     * JLImage::getResource()
     * Get resource form image loaded.
     * @return resource
     */
    function getResource() {
        return $this->_image;
    }

    /**
     * JLImage::getWidth()
     * Get width form image.
     * @return int
     */
    function getWidth() {
        return imagesx($this->_image);
    }

    /**
     * JLImage::getHeight()
     * Get height form image.
     * @return int
     */
    function getHeight() {
        return imagesy($this->_image);
    }

    /**
     * JLImage::resizeToHeight()
     * Resize proportional image form height.
     * @param int $height
     * @return void
     */
    function resizeToHeight($height) {
        $width = $this->getPropWidth($height);
        $this->resize($width, $height);
    }

    /**
     * JLImage::resizeToWidth()
     * Resize proportional image form width.
     * @param int $width
     * @return void
     */
    function resizeToWidth($width) {
        $height = $this->getPropHeight($width);
        $this->resize($width, $height);
    }

    /**
     * JLImage::getPropWidth()
     * Gets proportional image width from height value.
     * @param int $height
     * @return int
     */
    function getPropWidth($height) {
        $ratio = (int) $height / $this->getHeight();
        return $this->getWidth() * $ratio;
    }

    /**
     * JLImage::getPropHeight()
     * Gets proportional image height form width value.
     * @param int $width
     * @return int
     */
    function getPropHeight($width) {
        $ratio = (int) $width / $this->getWidth();
        return $this->getHeight() * $ratio;
    }

    /**
     * JLImage::scale()
     * Scale a image.
     * @param int $scale
     * @return void
     */
    function scale($scale) {
        $width = $this->getWidth() * (int) $scale / 100;
        $height = $this->getHeight() * (int) $scale / 100;
        $this->resize($width, $height);
    }

    /**
     * JLImage::centerCrop()
     * Cropping an image from the center.
     * @param int $width
     * @param int $height
     * @return void
     */
    function centerCrop($width, $height) {
        $pwidth = $this->getPropWidth($height);
        $pheight = $this->getPropHeight($width);

        if ($pwidth == $width && $pheight == $height) {
            $this->resizeToWidth($width);
        } else {
            if ($pheight > $height) {
                $this->resizeToWidth($width);
            } else {
                $pheight += $height - $pheight;
                $this->resizeToHeight($pheight);
            }

            $x = ($this->getWidth() - $width) / 2;
            $y = ($this->getHeight() - $height) / 2;
            $this->crop($width, $height, $x, $y);
        }
    }

    /**
     * JLImage::crop()
     * Crop to image.
     * @param int $width_crop
     * @param int $height_crop
     * @param int $x1
     * @param int $y1
     * @param int $dst_x
     * @param int $dst_y
     * @return void
     */
    function crop($width_crop, $height_crop, $x1 = 0, $y1 = 0, $dst_x = 0, $dst_y = 0) {
        $this->resize($width_crop, $height_crop, $x1, $y1, $dst_x, $dst_y, TRUE);
    }

    /**
     * JLImage::resize()
     * Resize to image.
     * @param int $width
     * @param int $height
     * @param int $x1
     * @param int $y1
     * @param int $dst_x
     * @param int $dst_y
     * @param bool $is_crop
     * @return void
     */
    private function resize($width, $height, $x1 = 0, $y1 = 0, $dst_x = 0, $dst_y = 0, $is_crop = FALSE) {
        if (!$this->_image)
            return;
        if ($this->_is_preserver) {
            $this->_image = $this->_original_image;
        }

        $new_image = imagecreatetruecolor($width, $height);

        if ($this->_image_type == IMAGETYPE_PNG) {
            imagealphablending($new_image, false);
            imagesavealpha($new_image, true);
        }

        imagecopyresampled($new_image, $this->_image, $dst_x, $dst_y, $x1, $y1, $width, $height, ($is_crop) ? $width : $this->getWidth(), ($is_crop) ? $height : $this->getHeight());
        $this->_image = $new_image;
    }

    /**
     * Image::imageDestroy()
     * Destroy an image resource.
     * @return bool
     */
    function imageDestroy() {
        @imagedestroy($this->_image);
        @imagedestroy($this->_original_image);
        $this->_image = NULL;
        $this->_original_image = NULL;
    }

}